package controller;

import java.sql.SQLException;
import java.util.Calendar;
import java.util.Date;
import java.util.Vector;

import view.FacturaView;
import view.LineaView;
import view.NuevoPlanPaqueteView;
import view.NumeroView;
import view.PlanView;
import view.PlanesView;
import view.UsuarioView;
import domain.Factura;
import domain.Linea;
import domain.Numero;
import domain.Paquete;
import domain.Plan;
import domain.Servicio;
import domain.Usuario;

public class SistemaTelefonia {

	private Vector<Usuario> usuarios;
	private Vector<Servicio> servicios;
	private Vector<Linea> lineas;
	private Vector<Plan> planes;
	private Vector<Numero> numeros;

	public SistemaTelefonia() {
		this.usuarios = new Vector<Usuario>();
		this.servicios = new Vector<Servicio>();
		this.lineas = new Vector<Linea>();
		this.planes = new Vector<Plan>();
		this.numeros = new Vector<Numero>();

		reloadData();
	}

	public void reloadData() {
		try {

			usuarios = Usuario.getUsuarios();
			planes = Plan.getPlanes();
			numeros = Numero.getNumeros();
			lineas = Linea.getLineas();

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public NumeroView getPrimerNumeroLibre() {
		numeros = Numero.getNumeros();
		for (Numero n : numeros)
			if (n.isDisponible()) {
				n.setDisponible(false);
				n.update();
				return n.getNumeroView();
			}
		return null;
	}

	public Vector<LineaView> getLineasView() {
		Vector<LineaView> lineasView = new Vector<LineaView>();
		for (Linea l : lineas) {
			
			// TODO: hacer otros valores
			lineasView.add(new LineaView(0, 0, 0, 0, l.getUsuario().getId(),l.getPlan().getView().getNombre()));
		}

		return lineasView;
	}

	public Vector getPlanes() {
		Vector p = new Vector();

		for (PlanView view : getPlanesView()) {
			p.add(view.toVector());
		}
		return p;
	}
	
	public Vector getFacturacion(String dni) {
		Vector p = new Vector();
		
		for (FacturaView view : getFacturasView(dni)) {
			p.add(view.toVector());
		}
		return p;
	}
	
	public Vector getUsuariosLista() {
		Vector p = new Vector();
		
		for (UsuarioView view : getUsuariosView()) {
			p.add(view.toVector());
		}
		return p;
	}
	
	public Vector<UsuarioView> getUsuariosView(){
		Vector<UsuarioView> views = new Vector<UsuarioView>();
		
		for (Usuario u : usuarios) {
			views.add(u.getView());
		}
		
		return views; 
	}
	
	
	public Vector<FacturaView> getFacturasView(String dni) {
		Usuario usuario = this.buscarUsuarioCore(dni);
		Vector<FacturaView> factView = new Vector<FacturaView>();
		if(usuario != null) {
			Vector<Factura> facturas = Factura.getFacturas(usuario.getId());
			if(facturas !=null && facturas.size()>0) {
				for (Factura f : facturas) {
					factView.add(f.getView());
				}
			}
		}
		return factView;
	}
	
	public Vector getPlanesAgregablesPaquete() {
		Vector p = new Vector();

		for (PlanView view : getPlanesAgregablesPaqueteView()) {
			p.add(view.toVector());
		}
		return p;
	}
	
	private Vector<PlanView> getPlanesAgregablesPaqueteView(){
		Vector<PlanView> planesView = new Vector<PlanView>();				

		for (Plan p : planes) {
			if (p.agregablePaquete())
				planesView.add(p.getView());			
		}

		return planesView;
	}
	
	

	public Vector<PlanView> getPlanesView() {
		reloadData();
		Vector<PlanView> planesView = new Vector<PlanView>();
		for (Plan p : planes) {
			planesView.add(p.getView());
		}

		return planesView;
	}

	public void setPlanes(Vector<Plan> planes) {
		// this.planes = planes;
	}

	public UsuarioView getUsuario(String dni) {
		for (Usuario u : usuarios)
			if (u.getDni().equals(dni))
				return u.getUsuarioView();
		return null;
	}

	public Vector<Usuario> getUsuarios() {
		return usuarios;
	}

	public void setUsuarios(Vector<Usuario> usuarios) {
		this.usuarios = usuarios;
	}

	public Vector<Servicio> getServicios() {
		return servicios;
	}

	public void setServicios(Vector<Servicio> servicios) {
		this.servicios = servicios;
	}

	public Vector<Linea> getLineas() {
		return lineas;
	}

	public void setLineas(Vector<Linea> lineas) {
		this.lineas = lineas;
	}

	public boolean crearUsuario(String dni, String nombre, String apellido,
			String domicilio, String telefono, String email) throws Exception {
		Usuario usuarioExistente = Usuario.get(dni);

		if (usuarioExistente != null
				&& (usuarioExistente.getEstado()).equals("Activo"))
			throw new Exception("El usuario con DNI: " + dni + " ya existe.");

		Usuario usuario = new Usuario(0, nombre, apellido, domicilio, dni, telefono, email, "Activo");
		this.usuarios.add(usuario);
		usuario.persistir();
		return true;
	}

	public void agregarUsuario(Usuario u) {

	}

	public boolean modificarUsuario(String dni, String nombre, String apellido,
			String domicilio, String telefono, String email) {
		Usuario usuario = this.buscarUsuarioCore(dni);
		if (usuario != null) {
			if (apellido.trim().length() != 0)
				usuario.setApellido(apellido);
			if (domicilio.trim().length() != 0)
				usuario.setDomicilio(domicilio);
			if (nombre.trim().length() != 0)
				usuario.setNombre(nombre);
			if (telefono.trim().length() != 0)
				usuario.setTelefono(telefono);
			if (email.trim().length() != 0)
				usuario.setEmail(email);
		}
		usuario.update();
		return true;
	}

	public boolean borrarUsuario(String dni) {
		Usuario usuario = this.buscarUsuarioCore(dni);
		if(usuario != null) {
			Vector<Linea> lineas = usuario.getLineas();
			if (tieneLineasActivas(lineas)) {
				realizarFacturacion(usuario);
	
				// borrar lineas
				for (Linea linea : lineas) {
					borrarLinea(linea);
				}
			}
	
			// borrar usuario
			this.getUsuarios().remove(usuario);
			usuario.setEstado("Inactivo");
			usuario.update();
	
			return true;
		}
		return false;
	}

	private boolean tieneLineasActivas(Vector<Linea> lineas) {
		for (Linea linea : lineas) {
			if (linea.getEstado().equals("Activa"))
				return true;
		}
		return false;
	}

	public UsuarioView buscarUsuario(String dni) {
		reloadData();
		for (Usuario u : usuarios) {
			if (u.getDni().equals(dni) && u.getEstado().equals("Activo"))
				return new UsuarioView(u.getId(), u.getDni(), u.getNombre(),
						u.getApellido(), u.getDomicilio(), u.getTelefono(),
						u.getEmail());
		}
		return null;
	}

	private Usuario buscarUsuarioCore(String dni) {
		reloadData();
		for (Usuario u : usuarios) {
			if (u.getDni().equals(dni) && !u.getEstado().equals("Inactivo"))
				return u;
		}
		return null;
	}

	// plan
	public void agregarPlan(Plan p) {

	}

	public void modificarPlan(Plan p) {

	}

	public void borrarPlan(Plan p) {

	}
	
	private Vector<Linea> getLineasFacturables() {
		Vector<Linea> l = new Vector<Linea>();
		
		for (Linea linea : this.lineas) {
			if (linea.getPlan().isFacturable())
				l.add(linea);
		}
		
		return l;
	}
	
	
	public boolean realizarFacturacion(Usuario usuario) {
		Vector<Linea> lineasAFacturar = null;
		if(usuario != null)
			lineasAFacturar = usuario.getLineas();
		
		 else
		 	lineasAFacturar = getLineasFacturables();
		
		for (Linea linea : lineasAFacturar) {
			Calendar i = Calendar.getInstance();
			i.add(Calendar.DAY_OF_MONTH, -15);// TODO: Parametros por UI?
			Date iniPeriodo = i.getTime();
			Calendar c = Calendar.getInstance();
			c.add(Calendar.DAY_OF_MONTH, 30);
			
			Date finPeriodo = c.getTime();
			
			Factura factura = linea.facturar(iniPeriodo, finPeriodo);
			factura.persistir();
		}
		return true;
	}
	
	// linea
	public boolean crearLinea(String usuarioDni, int numeroId, int planId,
			String nombre) {
		Numero numero = Numero.getNumero(numeroId);
		Plan plan = Plan.getPlan(planId);
		Usuario usuario = Usuario.get(usuarioDni);

		Linea nuevaLinea = new Linea(0, "Activa", Calendar.getInstance()
				.getTime(), Calendar.getInstance().getTime(), numero, plan,
				usuario, nombre);
		nuevaLinea.persistir();
		return true;
	}

	public void agregarLinea(Linea l) {

	}

	public void borrarLinea(Linea l) {
		this.getLineas().remove(l);
		l.setEstado("Inactivo");
		l.update();
	}

	public LineaView buscarLinea(String dni) {
		return null;
	}

	public PlanesView listarPlanes() {
		return null;
	}

	public void crearPlanPaquete(NuevoPlanPaqueteView nuevoPlanView) {
		Paquete paquete = new Paquete(0, nuevoPlanView.getNombre());

		for (int planId : nuevoPlanView.getPlanes()) {
			paquete.agregarPlan(Plan.getPlan(planId));
		}
		
		paquete.persistir();
	}

}
